package com.d.common.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;

/**
 * Redis 客服端
 * @ClassName:RedisUtil
 * @Description:
 */
public class RedisUtil {
    private  static Logger logger = LoggerFactory.getLogger(RedisUtil.class);

	private static final String LOCK_SUCCESS = "OK";
	private static final String SET_IF_NOT_EXIST = "NX";
	private static final String SET_WITH_EXPIRE_TIME = "PX";//PX表示超时时间是毫秒设置，EX表示超时时间是分钟设置
	private static final Long RELEASE_SUCCESS = 1L;

	/**
	 * jedis 连接池
	 */
	private static JedisPool jedisPool;

	private static JedisPool erpPool;

	@Resource
	public void setErpPool(JedisPool erpPool) {
		RedisUtil.erpPool = erpPool;
	}
	public static Jedis getErp(){
		return RedisUtil.erpPool.getResource();
	}


	@Resource
	public void setJedisPool(JedisPool jedisPool) {
		RedisUtil.jedisPool = jedisPool;
	}

	/**
	 * 释放连接对象
	 * @Title:closeShardedJedis
	 * @param jedis
	 * @return void
	 * @throws
	 */
	public static void closeJedis(Jedis jedis){
		if (null != jedis){
			//jedisPool.returnResource(jedis);
			jedis.close();
		}
	}


	/**
	 * 释放异常的连接对象
	 * @Title:closeShardedJedis
	 * @param jedis
	 * @return void
	 * @throws
	 */
	public static void closeBrokenJedis(Jedis jedis){
		if (null != jedis){
			//jedisPool.returnBrokenResource(jedis);
			jedis.close();
		}
	}
	/**
	 * 获取连接对象
	 * @Title:getShardedJedis
	 * @return ShardedJedis
	 * @throws
	 */
	public static Jedis getJedis(){
		return RedisUtil.jedisPool.getResource();
	}


	/**
	 * 根据redis的key找到对应的值
	 * @param jediskey  redis键
	 * @return  //返回redis储存信息
	 */
	public static String getJedisVal(String jediskey)
	{
		Jedis jedis =null;
		try
		{
			jedis =  RedisUtil.getJedis();
			String value = jedis.get(jediskey);
			return value;
		}
		catch(Exception e)
		{
			logger.error("key:"+jediskey+"未能取到redis的值.");
			closeBrokenJedis(jedis);
			return null;
		}
		finally
		{
			closeJedis(jedis);
		}
	}

	public static String getErpJedisVal(String jediskey)
	{
		Jedis jedis =null;
		try
		{
			jedis =  RedisUtil.getErp();
			String value = jedis.get(jediskey);
			return value;
		}
		catch(Exception e)
		{
			logger.error("key:"+jediskey+"未能取到redis的值.");
			closeBrokenJedis(jedis);
			return null;
		}
		finally
		{
			closeJedis(jedis);
		}
	}

	/**
	 * 存储redis的键值不设置时间
	 * @param jediskey  redis键
	 * @param jedisval  redis值
	 */
	public static void setJedisVal(String jediskey,String jedisval)
	{
		setJedisVal(jediskey,jedisval,0);
	}

	/**
	 * 设置时间存储redis
	 * @param jediskey  redis键
	 * @param jedisval  redis值
	 * @param seconds   时间(秒)
	 */
	public static void setErpJedisVal(String jediskey,String jedisval,int seconds)
	{
		Jedis jedis =null;
		try
		{
			jedis =  RedisUtil.getErp();

			if(seconds>0)
			{
				jedis.setex(jediskey, seconds, jedisval);
			}
			else
			{
				jedis.set(jediskey,jedisval);
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
			closeBrokenJedis(jedis);
		}
		finally
		{
			closeJedis(jedis);
		}
	}

	/**
	 * 设置时间存储redis
	 * @param jediskey  redis键
	 * @param jedisval  redis值
	 * @param seconds   时间(秒)
	 */
	public static void setJedisVal(String jediskey,String jedisval,int seconds)
	{
		Jedis jedis =null;
		try
		{
			jedis =  RedisUtil.getJedis();

			if(seconds>0)
			{
				jedis.setex(jediskey, seconds, jedisval);
			}
			else
			{
				jedis.set(jediskey,jedisval);
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
			closeBrokenJedis(jedis);
		}
		finally
		{
			closeJedis(jedis);
		}
	}
	/**
	 * 根据redis键值删除redis
	 * @param jediskey  键值
	 */
	public static void delJedis(String jediskey)
	{
		Jedis jedis =null;
		try
		{
			jedis =  RedisUtil.getJedis();
			jedis.del(jediskey);
		}
		catch(Exception e)
		{
			e.printStackTrace();
			closeBrokenJedis(jedis);
		}
		finally
		{
			closeJedis(jedis);
		}
	}

	public static void lpush(String key,String value){
		Jedis jedis =null;
		try
		{
			jedis =  RedisUtil.getJedis();
			jedis.lpush(key, value);
		}
		catch(Exception e)
		{
			e.printStackTrace();
			closeBrokenJedis(jedis);
		}
		finally
		{
			closeJedis(jedis);
		}
	}

	public static List<String> lrange(String key,Long start,Long end){
		Jedis jedis =null;
		try
		{
			jedis =  RedisUtil.getJedis();
			return jedis.lrange(key, start, end);
		}
		catch(Exception e)
		{
			e.printStackTrace();
			closeBrokenJedis(jedis);
			return null;
		}
		finally
		{
			closeJedis(jedis);
		}
	}

	public static Long llen(String key){
		Jedis jedis =null;
		try
		{
			jedis =  RedisUtil.getJedis();
			return jedis.llen(key);
		}
		catch(Exception e)
		{
			e.printStackTrace();
			closeBrokenJedis(jedis);
			return null;
		}
		finally
		{
			closeJedis(jedis);
		}
	}

	/**
	 * 尝试获取分布式锁
	 *
	 * @param lockKey    锁
	 * @param requestId  请求标识
	 * @param expireTime 超期时间
	 * @return 是否获取成功
	 */
	public static boolean tryGetDistributedLock(String lockKey, String requestId, int expireTime) {
		Jedis jedis = null;
		try {
			jedis = RedisUtil.getJedis();
			String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
			if (LOCK_SUCCESS.equals(result)) {
				return true;
			}
			return false;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		} finally {
			//归还连接到redis池中
			jedis.close();
		}
	}

	/**
	 * 释放分布式锁
	 *
	 * @param lockKey   锁
	 * @param requestId 请求标识
	 * @return 是否释放成功
	 */
	public static boolean releaseDistributedLock(String lockKey, String requestId) {
		Jedis jedis = null;
		try {
			jedis = RedisUtil.getJedis();
			String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
			Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
			if (RELEASE_SUCCESS.equals(result)) {
				return true;
			}
			return false;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		} finally {
			//归还连接到redis池中
			jedis.close();
		}
	}
}
